package com.cn.web.config;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.SignatureException;
import java.util.Arrays;
import java.util.List;

import static com.cn.common.utils.JwtUtils.secretKey;

@Aspect
@Component
public class MyAspect {

    @Before("execution(* com.cn.web.controller..*.*(..))")
    public void beforeMethodExecution(JoinPoint joinPoint) {
        // 获取当前请求的HttpServletRequest对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String requestURI = request.getRequestURI();
        if (isLoginPath(requestURI)) {
            System.out.println("登录路径放行");
            return ;
        }
        // 获取请求头信息
        String token = request.getHeader("Token");
        System.out.println("请求头中的Token: " + token);

        // 在这里可以进行对 Token 的判断逻辑
        if (token != null) {
            Claims claims = validateToken(token);
            // 如果validateToken返回null或者有异常，发送未授权的响应
            if (claims != null) {
                // 验证通过，获取token中的角色信息
                String role = extractRoleFromToken(token);
                if ("guest".equals(role)) {
                    if (isGuestPath(request.getRequestURI())) {
                        System.out.println("游客访问权限验证通过");
                    } else {
                        sendUnauthorizedResponse(request);
                    }
                } else if ("admin".equals(role)) {
                    // 如果是管理员，则允许访问
                    System.out.println("管理员访问权限验证通过");
                } else {
                    // 处理其他角色的逻辑，比如普通用户等
                    handleOtherRoles(role);
                }
            }

        }

    }

    private void sendUnauthorizedResponse(HttpServletRequest request) {
        // 发送未授权的响应
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json");

        try (PrintWriter writer = new PrintWriter(response.getOutputStream())) {
            writer.println("{\"error\": \"Unauthorized\"}");
        } catch (IOException e) {
            // 处理异常或记录日志
        }
    }
    private Claims validateToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException ex) {
            // Token已过期
            System.err.println("Token已过期: " + ex.getMessage());
        } catch (MalformedJwtException ex) {
            // Token格式错误
            System.err.println("无效的Token格式: " + ex.getMessage());
        } catch (Exception ex) {
            // 其他异常
            System.err.println("Token验证失败: " + ex.getMessage());
        }
        return null;
    }
        private String extractRoleFromToken(String token) {
        // 从token中解析出角色信息
        Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
        return claims.get("role", String.class);
    }
    private void handleOtherRoles(String role) {
        // 在这里处理其他角色的逻辑
        System.out.println("其他角色访问权限验证通过，角色为: " + role);
    }
    private boolean isGuestPath(String path) {
        // 在这里添加判断逻辑，确定是否是允许游客访问的路径
        // 例如，你可以定义一个列表，包含允许游客访问的路径
        List<String> guestPaths = Arrays.asList("/guest/login","/select/Menu","/select/Permissions/Button");
        return guestPaths.contains(path);
    }
    private boolean isLoginPath(String requestURI) {
        // 在这里添加判断逻辑，比如判断是否是登录接口的路径
        // 如果是登录路径，返回true，表示放行
        // 否则返回false，继续进行Token验证
        return "/guest/login".equals(requestURI) || "/login/Purposes".equals(requestURI);
    }

}